home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / music / dtcd101.zip / DTCD.ASM < prev    next >
Assembly Source File  |  1994-01-25  |  38KB  |  826 lines

  1. Code Segment
  2.      Assume Cs:Code,Ds:Code
  3.      Org 100h
  4.      .286
  5.  
  6. ;====----  Some constants for the scan-codes  ----============================
  7.  
  8.      ReleasedALT    EQU      0B8h                ;(Scan-code of ALT) OR 80h
  9.      KeyF11         EQU      57h                 ;F11 scan-code
  10.      KeyF12         EQU      KeyF11+1            ;IMPORTANT!
  11.      KeyVolumeDown  EQU      33h                 ;'<'
  12.      KeyVolumeUp    EQU      KeyVolumeDown+1     ;IMPORTANT!
  13.  
  14. ;====----  Some global constants  ----========================================
  15.  
  16.      KeyboardFlags  EQU      17h                 ;Keyboard-state bits
  17.      ALTNumericBuf  EQU      19h                 ;Buffer for ALT-numeric
  18.      VolumeSteps    EQU      5                   ;Inc/Dec volume by step
  19.      Done           EQU      100h                ;Bit indicating done
  20.      DeviceBusy     EQU      200h                ;Bit indicating device busy
  21.      ErrorBit       EQU      8000h               ;Bit indicating IOCTL-Error
  22.      MaxBlockLen    EQU      9                   ;MaxLen of IOCTL-Block
  23.  
  24. ;=============================================================================
  25.  
  26. Start:
  27.      Jmp      Initialization
  28.  
  29. TSR Proc Far
  30.      Cmp      Ah,4Fh                             ;Right sub-function?
  31.      Jz       Popup                              ;Yes -> popup
  32. CallOrgInt:
  33.      Jmp      DWord Ptr CS:[OrgIntOfs]           ;No -> original interrupt
  34. Popup:
  35.      Push     Bp                                 ;Save regs...
  36.      Mov      Bp,Sp
  37.      Push     Ds
  38.      Push     Es
  39.      Pusha
  40.      Push     Cs
  41.      Pop      Ds
  42.      Cmp      Bx,'DT'                            ;Installation check
  43.      Jnz      NoInitCheck
  44.      Cmp      Cx,'CD'
  45.      Jnz      NoInitCheck
  46.      Popa
  47.      Mov      Ax,'Yo'                            ;Return 'Yo'...
  48.      Jmp      ReturnAfterInitCheck               ;and return
  49. NoInitCheck:
  50.      Push     40h                                ;Set ES to BIOS Data Segment
  51.      Pop      Es
  52.      Cmp      Al,ReleasedALT                     ;ALT-key released?
  53.      Jz       JumpRequest                        ;Yes -> check for jump-req.
  54.      Test     Al,80h                             ;Any other released key ?
  55.      Jnz      ReturnFromPopup                    ;Released -> exit
  56. CheckForF11:
  57.      Cmp      Al,KeyF11                          ;F11 pressed
  58.      Jz       PlayControl                        ;Yes -> PlayControl
  59.      Cmp      Al,KeyF12                          ;F12 pressed
  60.      Jz       PlayControl                        ;Yes -> Playcontrol
  61.      Cmp      Al,KeyVolumeDown                   ;'<' pressed
  62.      Jz       VolumeControl                      ;Yes -> Volumecontrol
  63.      Cmp      Al,KeyVolumeUp                     ;'>' pressed
  64.      Jz       VolumeControl                      ;Yes -> Volumecontrol
  65.      Jmp      ReturnFromPopup
  66. JumpRequest:
  67.      Mov      Al,ES:[KeyboardFlags]              ;Get keyboard flags
  68.      And      Al,3                               ;Check if a shift is pressed
  69.      Jz       ReturnFromPopup                    ;No -> exit
  70.      Call     JumpToTrack                        ;Perform JumpRequest
  71.      Jmp      ReturnFromPopup                    ;No carry-clear after this!
  72. PlayControl:
  73.      Sub      Al,KeyF11                          ;F11 -> AL=0, F12 -> AL=1
  74.      Mov      Si,Offset RequestNumber            ;Array with request offsets
  75.      Jmp      HandleKey
  76. VolumeControl:
  77.      Sub      Al,KeyVolumeDown                   ;'<' -> AL=0, '>' -> AL=1
  78.      Mov      Si,Offset VolumeRequest            ;Array with request offsets
  79. HandleKey:
  80.      Sub      Bh,Bh                              ;Clear BH
  81.      Mov      Bl,ES:[KeyboardFlags]              ;Get keyboard bits in BL
  82.      And      Bl,15                              ;Filter CTRL/ALT/SHIFT-keys
  83.      Mov      Ah,[Si+Bx]                         ;Get request number in AH
  84.      Or       Ah,Ah                              ;Request 0 ?
  85.      Jz       ReturnFromPopup                    ;Yes -> No request, exit
  86.      Dec      Ah                                 ;Calc appropriate function
  87.      Mov      Bl,Ah
  88.      Add      Bl,Al
  89.      Shl      Bx,1
  90.      Push     Cs                                 ;Set ES to CS
  91.      Pop      Es
  92.      Cmp      [Busy],1                           ;Already busy?
  93.      Jz       DontDoRequest                      ;Yes -> don't interfere
  94.      Mov      [Busy],1                           ;Set busy flag
  95.      Call     [RequestHandlr+Bx]                 ;Call request-handler
  96.      Mov      [Busy],0                           ;Clear busy flag
  97. DontDoRequest:
  98.      And      Word Ptr [Bp+6],0FFFEh             ;Clear original carry-flag
  99. ReturnFromPopup:
  100.      Popa                                        ;Pop registers
  101. ReturnAfterInitCheck:
  102.      Pop      Es                                 ;Exit...
  103.      Pop      Ds
  104.      Pop      Bp
  105.      Iret
  106. Endp
  107.  
  108. PrepareIOCTL Proc Near                           ;Setup variables for IOCTL
  109.      Mov      [IOCTLBlockLen],14h                ;See CDROM.LST for details
  110.      Mov      [IOCTLTransOfs],Offset IOCTLBuffer
  111.      Mov      [IOCTLTransSeg],Ds
  112.      Mov      [IOCTLLen],Cx
  113.      Mov      Bx,Offset IOCTLBlock
  114.      Mov      Ax,1510h
  115.      Mov      Cx,[CDROMDrive]
  116.      Ret
  117. Endp
  118.  
  119. IOCTLOutput Proc Near
  120.      Call     PrepareIOCTL                       ;Setup IOCTL variables
  121.      Mov      [IOCTLCommand],0Ch                 ;Output command
  122. TryOutputAgain:
  123.      Int      2Fh                                ;Perform IOCTL-output
  124.      Test     [IOCTLStatus],Done                 ;Request ok ?
  125.      Jz       TryOutputAgain                     ;No -> try again
  126.      Ret
  127. Endp
  128.  
  129. IOCTLInput Proc Near
  130.      Call     PrepareIOCTL                       ;Setup IOCTL variables
  131.      Mov      [IOCTLCommand],3                   ;Input command
  132. TryInputAgain:
  133.      Int      2Fh                                ;Perform IOCTL-input
  134.      Test     [IOCTLStatus],Done                 ;Request ok ?
  135.      Jz       TryInputAgain                      ;No -> try again
  136.      Ret
  137. Endp
  138.  
  139. DirectCommand Proc Near                          ;Send a direct command...
  140.      Mov      Ax,1510h
  141.      Mov      Bx,Offset IOCTLBlock
  142.      Mov      Cx,[CDROMDrive]
  143.      Int      2Fh
  144.      Ret
  145. Endp
  146.  
  147. RedBookToHSG Proc Near                           ;In: DS:[SI]=Red Book sector
  148.      Push     Bx                                 ;Out:  DX:AX=HSG sector
  149.      Push     Cx
  150.      Mov      Al,75
  151.      Mul      Byte Ptr [Si+1]
  152.      Mov      Bx,Ax
  153.      Sub      Ah,Ah
  154.      Mov      Al,[Si+2]
  155.      Mov      Cx,4500
  156.      Mul      Cx
  157.      Add      Ax,Bx
  158.      Adc      Dx,0
  159.      Add      Al,[Si]
  160.      Adc      Ah,0
  161.      Adc      Dx,0
  162.      Sub      Ax,150
  163.      Sbb      Dx,0
  164.      Pop      Cx
  165.      Pop      Bx
  166.      Ret
  167. Endp
  168.  
  169. SaveCurPos Proc Near                             ;Saves drive-head position
  170.      Mov      [IOCTLBuffer],1                    ;CD-ROM request 1
  171.      Mov      [IOCTLBuffer+1],0                  ;HSG addressing
  172.      Mov      Cx,6                               ;Expects 6 bytes
  173.      Call     IOCTLInput                         ;Get the input
  174.      Mov      Ax,Word Ptr [IOCTLBuffer+2]        ;Copy to HSGINDEX
  175.      Mov      Word Ptr [HSGIndex],Ax
  176.      Mov      Ax,Word Ptr [IOCTLBuffer+4]
  177.      Mov      Word Ptr [HSGIndex+2],Ax
  178.      Ret
  179. Endp
  180.  
  181. GetCDInfo Proc Near                              ;Gets CD information
  182.      Mov      [IOCTLBuffer],0Ah                  ;CD-ROM request 10
  183.      Mov      Cx,7                               ;Expects 7 bytes
  184.      Call     IOCTLInput                         ;Get the input
  185.      Test     [IOCTLStatus],ErrorBit             ;Error occured ?
  186.      Jnz      ExitGetInfo                        ;Yes -> exit procedure
  187.      Mov      Al,[IOCTLBuffer+1]                 ;Copy data from buffer
  188.      Mov      [MinTrack],Al
  189.      Mov      Al,[IOCTLBuffer+2]
  190.      Mov      [MaxTrack],Al
  191.      Mov      Si,Offset IOCTLBuffer+3
  192.      Call     RedBookToHSG                       ;Convert last sector
  193.      Mov      Word Ptr [MaxIndex],Ax             ;Save as last audio-sector
  194.      Mov      Word Ptr [MaxIndex+2],Dx
  195.      Mov      Cl,[MinTrack]
  196.      Call     GetTrackInfo                       ;Get info of the first track
  197.      Mov      Si,Offset IOCTLBuffer+2
  198.      Call     RedBookToHSG                       ;Convert starting sector
  199.      Mov      Word Ptr [MinIndex],Ax             ;Save as first audio-sector
  200.      Mov      Word Ptr [MinIndex+2],Dx
  201. ExitGetInfo:
  202.      Ret
  203. Endp
  204.  
  205. CDLoaded Proc Near                               ;Returns: ZF=0 if CD loaded
  206.      Mov      [IOCTLBuffer],6                    ;CD-ROM request 6
  207.      Mov      Cx,5                               ;Expects 5 bytes
  208.      Call     IOCTLInput                         ;Get the input
  209.      Test     Word Ptr [IOCTLBuffer+1],1         ;Filter data
  210.      Ret
  211. Endp
  212.  
  213. GetTrackInfo Proc Near                           ;Returns track info in buffer
  214.      Mov      [IOCTLBuffer],0Bh                  ;CD-ROM request 11
  215.      Mov      [IOCTLBuffer+1],Cl                 ;Info on track CL
  216.      Mov      Cx,8                               ;Expects 8 bytes
  217.      Call     IOCTLInput                         ;Get the input
  218.      Ret
  219. Endp
  220.  
  221. GetCurTrack Proc Near                            ;Returns: CL=current track
  222.      Call     SaveCurPos                         ;Save current position
  223. GetCurTrackFromIndex:                            ;External entry...
  224.      Mov      Cl,[MinTrack]                      ;Setup vars before loop
  225.      Dec      Cl                                 ;  (CL=MinTrack-1)
  226. WalkToTrackLoop:
  227.      Inc      Cl                                 ;Increase track number
  228.      Cmp      Cl,[MaxTrack]                      ;Is it bigger than MaxTrack
  229.      Ja       DecreaseTrack                      ;Yes -> exit loop
  230.      Push     Cx                                 ;Save track number
  231.      Call     GetTrackInfo                       ;Get track info
  232.      Pop      Cx                                 ;Restore track number
  233.      Mov      Si,Offset IOCTLBuffer+2            ;Calc start sector of track
  234.      Call     RedBookToHSG                       ;Calc...
  235.      Mov      Si,Offset HSGIndex                 ;Compare to current position
  236.      Call     CompareIndexes                     ;Compare...
  237.      Jb       WalkToTrackLoop                    ;If below, repeat loop
  238. DecreaseTrack:
  239.      Dec      Cl                                 ;Decrease track number
  240.      Ret
  241. Endp
  242.  
  243. GetVolumeSettings Proc Near                      ;Get vol.settings in buffer
  244.      Mov      [IOCTLBuffer],4                    ;CD-ROM request 4
  245.      Mov      Cx,9                               ;Expects 9 bytes
  246.      Call     IOCTLInput                         ;Get the input
  247.      Ret
  248. Endp
  249.  
  250. SetVolumeSettings Proc Near                      ;Set vol.settings from buffer
  251.      Mov      [IOCTLBuffer],3                    ;CD-ROM request 3
  252.      Mov      Cx,9                               ;Expects 9 bytes
  253.      Call     IOCTLOutput                        ;Write the output
  254.      Ret
  255. Endp
  256.  
  257. PlayFromTrack Proc Near                          ;Plays from track to the end
  258.      Call     GetTrackInfo                       ;Get the track info
  259.      Mov      Si,Offset IOCTLBuffer+2            ;Convert to HSG-indexing
  260.      Call     RedBookToHSG
  261.      Mov      Word Ptr [HSGIndex],Ax             ;Save as sector to start play
  262.      Mov      Word Ptr [HSGIndex+2],Dx
  263.      Call     PlayCD                             ;Play
  264.      Ret
  265. Endp
  266.  
  267. IsAudioTrack Proc Near                           ;Returns: ZF=0 if audio-track
  268.      Call     GetTrackInfo                       ;Get the track info
  269.      Mov      Al,[IOCTLBuffer+6]                 ;Get track-bits in AL
  270.      And      Al,50h                             ;Filter audio-bits
  271.      Jz       AudioTrack                         ;Jump if audio-track
  272.      Cmp      Al,10h                             ;Another posibility
  273.      Jz       AudioTrack                         ;Jump if audio-track
  274. NoAudioTrack:
  275.      Mov      Al,1                               ;Return ZF=1...
  276. AudioTrack:
  277.      And      Al,1                               ;Set the zero-flag
  278.      Ret
  279. Endp
  280.  
  281. GetNextAudioTrack Proc Near                      ;Returns: CL=next audio-track
  282.      Or       Cl,Cl                              ;Is CL 0 ?
  283.      Jnz      CheckNextFromHere                  ;No -> don't initialize
  284.      Mov      Cl,[MinTrack]                      ;Set CL to (MinTrack-1)
  285.      Dec      Cl
  286. CheckNextFromHere:
  287.      Inc      Cl                                 ;Increase track number
  288.      Cmp      Cl,[MaxTrack]                      ;Is it bigger than MaxTrack
  289.      Ja       NoNextTrackFound                   ;Yes -> exit
  290.      Push     Cx                                 ;Save track number
  291.      Call     IsAudioTrack                       ;Is it an audio-track ?
  292.      Pop      Cx                                 ;Restore track number
  293.      Jnz      CheckNextFromHere                  ;No -> check next track
  294.      Jmp      NextAudioTrackFound                ;Audio track found...
  295. NoNextTrackFound:
  296.      Sub      Cl,Cl                              ;Return 0 (no more tracks)
  297. NextAudioTrackFound:
  298.      Ret
  299. Endp
  300.  
  301. GetPrevAudioTrack Proc Near                      ;Returns: CL=prev audio-track
  302.      Or       Cl,Cl                              ;Is CL 0 ?
  303.      Jnz      CheckPrevFromHere                  ;No -> don't initialize
  304.      Mov      Cl,[MaxTrack]                      ;Set CL to (MaxTrack+1)
  305.      Inc      Cl
  306. CheckPrevFromHere:
  307.      Dec      Cl                                 ;Decrease track number
  308.      Cmp      Cl,[MinTrack]                      ;Is it smaller than MinTrack
  309.      Jb       NoPrevTrackFound                   ;Yes -> exit
  310.      Push     Cx                                 ;Save track number
  311.      Call     IsAudioTrack                       ;Is it an audio-track ?
  312.      Pop      Cx                                 ;Restore track number
  313.      Jnz      CheckPrevFromHere                  ;No -> check prev track
  314.      Jmp      PrevAudioTrackFound                ;Audio track found...
  315. NoPrevTrackFound:
  316.      Sub      Cl,Cl                              ;Return 0 (no more tracks)
  317. PrevAudioTrackFound:
  318.      Ret
  319. Endp
  320.  
  321. CompareIndexes Proc Near                         ;Compares DX:AX to [SI]
  322.      Cmp      Dx,[Si+2]                          ;Is DX equal to [SI+2]
  323.      Jne      EndOfComparison                    ;No -> exit (flags correct)
  324.      Cmp      Ax,[Si]                            ;Compare AX to [SI]
  325. EndOfComparison:
  326.      Ret                                         ;(Flags updated)
  327. Endp
  328.  
  329. JumpToTrack Proc Near                            ;Play directly from track
  330.      Push     Es                                 ;Save BIOS Data Segment
  331.      Push     Cs                                 ;Set ES to CS
  332.      Pop      Es
  333.      Call     GetCDInfo                          ;Get CD info
  334.      Pop      Es                                 ;Restore BIOS Data Segment
  335.      Sub      Cl,Cl                              ;Set 0 in ALT-Num buffer,
  336.      Xchg     Cl,ES:[ALTNumericBuf]              ;and set CL to track-number
  337.      Cmp      Cl,[MinTrack]                      ;Is it smaller than MinTrack
  338.      Jb       ExitJumpToTrack                    ;Yes -> don't jump...
  339.      Cmp      Cl,[MaxTrack]                      ;Is it bigger than MaxTrack
  340.      Ja       ExitJumpToTrack                    ;Yes -> don't jump
  341.      Push     Cx                                 ;Save track number
  342.      Call     IsAudioTrack                       ;Is it an audio-track
  343.      Pop      Cx                                 ;Restore track number
  344.      Jnz      ExitJumpToTrack                    ;No -> exit
  345.      Push     Cs                                 ;Set ES to CS
  346.      Pop      Es
  347.      Call     PlayFromTrack                      ;Play from track...
  348. ExitJumpToTrack:
  349.      Ret
  350. Endp
  351.  
  352. UnlockDoor Proc Near                             ;Unlocks the drive door
  353.      Mov      [IOCTLBuffer],1                    ;CD-ROM request 1
  354.      Mov      [IOCTLBuffer+1],0                  ;0=Unlock door (1=Lock)
  355.      Mov      Cx,2                               ;Expects 2 bytes
  356.      Call     IOCTLOutput                        ;Write the output
  357.      Ret
  358. Endp
  359.  
  360. EjectCD Proc Near                                ;Ejects the CD
  361.      Call     StopCD                             ;First stop playing
  362.      Call     UnlockDoor                         ;Then unlock door
  363.      Mov      [IOCTLBuffer],0                    ;CD-ROM request 0
  364.      Mov      Cx,1                               ;Expects 1 byte
  365.      Call     IOCTLOutput                        ;Write the output
  366.      Ret
  367. Endp
  368.  
  369. LoadCD Proc Near                                 ;Closes the drive door
  370.      Call     CDLoaded                           ;Is CD already loaded ?
  371.      Jz       ExitLoadCD                         ;Yes -> exit
  372.      Mov      [IOCTLBuffer],5                    ;CD-ROM request 5
  373.      Mov      Cx,1                               ;Expects 1 byte
  374.      Call     IOCTLOutput                        ;Write the output
  375. ExitLoadCD:
  376.      Ret
  377. Endp
  378.  
  379. StopCD Proc Near                                 ;Stop playing ('pause')
  380.      Push     Word Ptr [HSGIndex]                ;Save index
  381.      Push     Word Ptr [HSGIndex+2]
  382.      Call     SaveCurPos                         ;Get current position
  383.      Test     [IOCTLStatus],DeviceBusy           ;Is audio playing ?
  384.      Jz       RestartCD                          ;No -> restart CD
  385.      Mov      [IOCTLCommand],85h                 ;IOCTL request 133
  386.      Mov      [IOCTLBlockLen],0Dh                ;Set IOCTL blocklength
  387.      Call     DirectCommand                      ;Execute a direct command
  388.      Mov      Ax,Word Ptr [HSGIndex]             ;Save index in restartaddress
  389.      Mov      Word Ptr [StartAddress],Ax
  390.      Mov      Ax,Word Ptr [HSGIndex+2]
  391.      Mov      Word Ptr [StartAddress+2],Ax
  392.      Jmp      ExitStopCD                         ;Leave procedure
  393. RestartCD:
  394.      Mov      Word Ptr [StartAddress],0          ;Set start index to 0
  395.      Mov      Word Ptr [StartAddress+2],0        ; (play from first track)
  396. ExitStopCD:
  397.      Pop      Word Ptr [HSGIndex+2]              ;Restore original index
  398.      Pop      Word Ptr [HSGIndex]
  399.      Ret
  400. Endp
  401.  
  402. PlayCD Proc Near                                 ;Play CD from [HSGINDEX]
  403.      Call     StopCD                             ;Stop CD first
  404.      Mov      Si,Offset HSGIndex                 ;Copy sectors into buffer
  405.      Mov      Ax,Word Ptr [HSGIndex]
  406.      Mov      Word Ptr [CDStartPlay],Ax
  407.      Mov      Ax,Word Ptr [HSGIndex+2]
  408.      Mov      Word Ptr [CDStartPlay+2],Ax
  409.      Mov      Ax,Word Ptr [MaxIndex]             ;To the last audio-sector
  410.      Mov      Dx,Word Ptr [MaxIndex+2]
  411.      Sub      Ax,[Si]                            ;Subtract the starting sector
  412.      Sbb      Dx,[Si+2]
  413.      Mov      Word Ptr [CDStopPlay],Ax           ;Set the number of sectors
  414.      Mov      Word Ptr [CDStopPlay+2],Dx         ; to play
  415.      Mov      [IOCTLCommand],84h                 ;IOCTL request 132
  416.      Mov      [IOCTLBlockLen],16h                ;Set IOCTL blocklength
  417.      Call     DirectCommand                      ;Execute a direct command
  418.      Mov      Word Ptr [StartAddress],0          ;Reset the start address
  419.      Mov      Word Ptr [StartAddress+2],0
  420.      Ret
  421. Endp
  422.  
  423. PrevTrack Proc Near                              ;Jumps a track backwards
  424.      Call     GetCDInfo                          ;Get CD info
  425.      Call     GetCurTrack                        ;Get the current track
  426.      Call     GetPrevAudioTrack                  ;Get the previous track
  427.      Or       Cl,Cl                              ;Track found ?
  428.      Jz       AtFirstAudioTrack                  ;No -> exit
  429.      Call     PlayFromTrack                      ;Play from track...
  430. AtFirstAudioTrack:
  431.      Ret
  432. Endp
  433.  
  434. NextTrack Proc Near                              ;Jumps a track forward
  435.      Call     GetCDInfo                          ;Get CD info
  436.      Call     GetCurTrack                        ;Get the current track
  437.      Call     GetNextAudioTrack                  ;Get the next track
  438.      Or       Cl,Cl                              ;Track found ?
  439.      Jz       AtLastAudioTrack                   ;No -> exit
  440.      Call     PlayFromTrack                      ;Play from track...
  441. AtLastAudioTrack:
  442.      Ret
  443. Endp
  444.  
  445. Skip10Sex Proc Near                              ;Jump 10 seconds forward
  446.      Call     GetCDInfo                          ;Get CD info
  447.      Call     SaveCurPos                         ;Save current position
  448.      Mov      Ax,Word Ptr [HSGIndex]             ;Check if sector ok...
  449.      Mov      Dx,Word Ptr [HSGIndex+2]
  450.      Add      Ax,750                             ;Add 750 frames=10 secs
  451.      Adc      Dx,0
  452.      Mov      Si,Offset MaxIndex
  453.      Call     CompareIndexes                     ;Compare to MaxIndex
  454.      Jae      DontSkip                           ;Above MaxIndex -> exit
  455.      Push     Ax                                 ;Save in HSGIndex
  456.      Push     Dx
  457.      Call     GetCurTrack                        ;Get current track
  458.      Pop      Word Ptr [HSGIndex+2]              ;Save...
  459.      Pop      Word Ptr [HSGIndex]
  460.      Push     Cx                                 ;Save current track
  461.      Call     GetCurTrackFromIndex               ;Get track to jump to
  462.      Pop      Ax                                 ;Restore current track
  463.      Cmp      Al,Cl                              ;Jump within same track ?
  464.      Jz       Skip                               ;Yes -> skip
  465.      Call     IsAudioTrack                       ;Is that track an audio track
  466.      Jnz      DontSkip                           ;No -> don't skip
  467. Skip:
  468.      Call     PlayCD                             ;Jump 10 seconds forward
  469. DontSkip:
  470.      Ret
  471. Endp
  472.  
  473. Backup10Sex Proc Near                            ;Jump 10 seconds backward
  474.      Call     GetCDInfo                          ;Get CD info
  475.      Call     SaveCurPos                         ;Save current position
  476.      Mov      Ax,Word Ptr [HSGIndex]             ;Check if sector is ok...
  477.      Mov      Dx,Word Ptr [HSGIndex+2]
  478.      Or       Dx,Dx                              ;Check if above frame #750
  479.      Jnz      OKToSubstract
  480.      Cmp      Ax,750
  481.      Jb       DontBackup                         ;Not above -> exit
  482. OKToSubstract:
  483.      Sub      Ax,750                             ;Substract 750 frames=10 secs
  484.      Sbb      Dx,0
  485.      Mov      Si,Offset MinIndex
  486.      Call     CompareIndexes                     ;Compare to MinIndex
  487.      Jbe      DontBackup                         ;Below MinIndex -> exit
  488.      Push     Ax                                 ;Save in HSGIndex
  489.      Push     Dx
  490.      Call     GetCurTrack                        ;Get current track
  491.      Pop      Word Ptr [HSGIndex+2]              ;Save...
  492.      Pop      Word Ptr [HSGIndex]
  493.      Push     Cx                                 ;Save current track
  494.      Call     GetCurTrackFromIndex               ;Get track to jump to
  495.      Pop      Ax                                 ;Restore current track
  496.      Cmp      Al,Cl                              ;Jump within same track ?
  497.      Jz       Backup                             ;Yes -> backup
  498.      Call     IsAudioTrack                       ;Is that track an audio track
  499.      Jnz      DontBackup                         ;No -> don't backup
  500. Backup:
  501.      Call     PlayCD                             ;Jump 10 seconds backwards
  502. DontBackup:
  503.      Ret
  504. Endp
  505.  
  506. IncreaseVolume Proc Near                         ;Input: CL=Channel bits
  507.      Push     Cx                                 ;Save channel bits
  508.      Call     GetVolumeSettings                  ;Get current settings
  509.      Pop      Cx                                 ;Restore channel bits
  510.      Mov      Bx,Offset IOCTLBuffer+2            ;First offset in buffer
  511. IncVolumeLoop:
  512.      Or       Cl,Cl                              ;Is CL 0 ?
  513.      Jz       ExitIncVolumeLoop                  ;Yes -> exit
  514.      Test     Cl,1                               ;Increase this channel ?
  515.      Jz       NextChannelCheckInc                ;No -> next channel
  516.      Cmp      Byte Ptr [Bx],256-VolumeSteps      ;Addition allowed ?
  517.      Jae      VolumeToMax                        ;No -> simply set to max
  518.      Add      Byte Ptr [Bx],VolumeSteps          ;Add...
  519.      Jmp      NextChannelCheckInc
  520. VolumeToMax:
  521.      Mov      Byte Ptr [Bx],255                  ;Set volume to maximum
  522. NextChannelCheckInc:
  523.      Shr      Cl,1                               ;Check next channel
  524.      Add      Bx,2                               ;2 bytes further in buffer
  525.      Jmp      IncVolumeLoop                      ;Next loop
  526. ExitIncVolumeLoop:
  527.      Call     SetVolumeSettings                  ;And write the settings
  528.      Ret
  529. Endp
  530.  
  531. DecreaseVolume Proc Near                         ;Input: CL=Channel bits
  532.      Push     Cx                                 ;Save channel bits
  533.      Call     GetVolumeSettings                  ;Get current settings
  534.      Pop      Cx                                 ;Restore channel bits
  535.      Mov      Bx,Offset IOCTLBuffer+2            ;First offset in buffer
  536. DecVolumeLoop:
  537.      Or       Cl,Cl                              ;Is CL 0 ?
  538.      Jz       ExitDecVolumeLoop                  ;Yes -> exit
  539.      Test     Cl,1                               ;Decrease this channel ?
  540.      Jz       NextChannelCheckDec                ;No -> next channel
  541.      Cmp      Byte Ptr [Bx],VolumeSteps-1        ;Substraction allowed ?
  542.      Jbe      VolumeToMin                        ;No -> simply set to min
  543.      Sub      Byte Ptr [Bx],VolumeSteps          ;Substract...
  544.      Jmp      NextChannelCheckDec
  545. VolumeToMin:
  546.      Mov      Byte Ptr [IOCTLBuffer+Bx],0        ;Set volume to minimum
  547. NextChannelCheckDec:
  548.      Shr      Cl,1                               ;Check next channel
  549.      Add      Bx,2                               ;2 bytes further in buffer
  550.      Jmp      DecVolumeLoop                      ;Next loop
  551. ExitDecVolumeLoop:
  552.      Call     SetVolumeSettings                  ;And write the settings
  553.      Ret
  554. Endp
  555.  
  556. StopRequest Proc Near                            ;Called upon F11 press
  557.      Call     CDLoaded                           ;Check if CD loaded
  558.      Jnz      ExitStopRequest                    ;No -> exit
  559.      Call     StopCD                             ;Stop playing
  560. ExitStopRequest:
  561.      Ret
  562. Endp
  563.  
  564. PlayRequest Proc Near                            ;Called upon F12
  565.      Call     CDLoaded                           ;Check if CD loaded
  566.      Jnz      LoadAndPlay                        ;No -> load and start playing
  567. TryToGetInfoAgain:
  568.      Call     GetCDInfo                          ;Get CD info
  569.      Test     [IOCTLStatus],ErrorBit             ;Error ?
  570.      Jnz      TryToGetInfoAgain                  ;Yes -> try again
  571.      Test     [IOCTLStatus],DeviceBusy           ;Already playing ?
  572.      Jnz      RestartTrack                       ;Yes -> restart track
  573.      Cmp      Word Ptr [StartAddress],0          ;Restart CD ?
  574.      Jnz      ContinuePlay                       ;No -> continue play
  575.      Cmp      Word Ptr [StartAddress+2],0        ;Restart CD ?
  576.      Jnz      ContinuePlay                       ;No -> continue play
  577.      Jmp      NotReadyYet                        ;Start playing
  578. ContinuePlay:
  579.      Call     GetCurTrack                        ;Get current track
  580.      Or       Cl,Cl                              ;Even before MinTrack ?
  581.      Jz       StartAtFirstTrack                  ;Yes -> restart CD
  582.      Mov      Ax,Word Ptr [StartAddress]         ;Copy startaddress into
  583.      Mov      Word Ptr [HSGIndex],Ax             ; HSGIndex
  584.      Mov      Ax,Word Ptr [StartAddress+2]
  585.      Mov      Word Ptr [HSGIndex+2],Ax
  586.      Call     PlayCD                             ;Play from index
  587.      Jmp      ExitPlayRequest
  588. LoadAndPlay:
  589.      Call     LoadCD                             ;Load CD
  590. NotReadyYet:
  591.      Call     GetCDInfo                          ;Get CD info
  592.      Test     [IOCTLStatus],ErrorBit             ;Error ?
  593.      Jnz      NotReadyYet                        ;Yes -> try again
  594. StartAtFirstTrack:
  595.      Sub      Cl,Cl                              ;Search for first audio track
  596.      Call     GetNextAudioTrack                  ;Search...
  597.      Or       Cl,Cl                              ;Audio track found ?
  598.      Jz       ExitPlayRequest                    ;No -> exit
  599.      Call     PlayFromTrack                      ;Play from track...
  600.      Jmp      ExitPlayRequest
  601. RestartTrack:
  602.      Call     GetCurTrack                        ;Get current track
  603.      Call     PlayFromTrack                      ;Play from track...
  604. ExitPlayRequest:
  605.      Ret
  606. Endp
  607.  
  608. EjectRequest Proc Near                           ;Called upon SHIFT-F11
  609.      Call     UnlockDoor                         ;Unlock drive door
  610.      Call     EjectCD                            ;Eject disc
  611.      Ret
  612. Endp
  613.  
  614. LoadRequest Proc Near                            ;Called upon SHIFT-F12
  615.      Call     LoadCD                             ;Load CD
  616.      Ret
  617. Endp
  618.  
  619. PrevRequest Proc Near                            ;Called upon CTRL-F11
  620.      Call     PrevTrack                          ;Jump to previous track
  621.      Ret
  622. Endp
  623.  
  624. NextRequest Proc Near                            ;Called upon CTRL-F12
  625.      Call     NextTrack                          ;Jump to next track
  626.      Ret
  627. Endp
  628.  
  629. BackRequest Proc Near                            ;Called upon ALT-F11
  630.      Call     Backup10Sex                        ;Jump 10 secs backwards
  631.      Ret
  632. Endp
  633.  
  634. SkipRequest Proc Near                            ;Called upon CTRL-F12
  635.      Call     Skip10Sex                          ;Jump 10 secs forwards
  636.      Ret
  637. Endp
  638.  
  639. LVUpRequest Proc Near                            ;Called upon ALT-LSHIFT-'>'
  640.      Mov      Cl,0101b                           ;Channels 0 and 2
  641.      Call     IncreaseVolume                     ;Increase volume
  642.      Ret
  643. Endp
  644.  
  645. LVDnRequest Proc Near                            ;Called upon ALT-LSHIFT-'<'
  646.      Mov      Cl,0101b                           ;Channels 0 and 2
  647.      Call     DecreaseVolume                     ;Decrease volume
  648.      Ret
  649. Endp
  650.  
  651. RVUpRequest Proc Near                            ;Called upon ALT-RSHIFT-'>'
  652.      Mov      Cl,1010b                           ;Channels 1 and 3
  653.      Call     IncreaseVolume                     ;Increase volume
  654.      Ret
  655. Endp
  656.  
  657. RVDnRequest Proc Near                            ;Called upon ALT-RSHIFT-'<'
  658.      Mov      Cl,1010b                           ;Channels 1 and 3
  659.      Call     DecreaseVolume                     ;Decrease volume
  660.      Ret
  661. Endp
  662.  
  663. LRVURequest Proc Near                            ;Called upon ALT-'>'
  664.      Mov      Cl,1111b                           ;Channels 0, 1, 2 and 3
  665.      Call     IncreaseVolume                     ;Increase volume
  666.      Ret
  667. Endp
  668.  
  669. LRVDRequest Proc Near                            ;Called upon ALT-'<'
  670.      Mov      Cl,1111b                           ;Channels 0, 1, 2 and 3
  671.      Call     DecreaseVolume                     ;Decrease volume
  672.      Ret
  673. Endp
  674.  
  675. ;====----  TSR Variables  ----================================================
  676.  
  677. Busy          Db    0                            ;Busy flag
  678.                                                  ;Change these arrays to
  679.                                                  ;swap/add commands:
  680. RequestNumber Db    01,03,03,03,05,00,00,00      ;Play requests
  681.               Db    07,00,00,00,00,00,00,00
  682. VolumeRequest Db    00,00,00,00,00,00,00,00      ;Volume requests
  683.               Db    13,11,09,13,00,00,00,00
  684. RequestHandlr Dw    Offset StopRequest,Offset PlayRequest       ;01+02
  685.               Dw    Offset EjectRequest,Offset LoadRequest      ;03+04
  686.               Dw    Offset PrevRequest,Offset NextRequest       ;05+06
  687.               Dw    Offset BackRequest,Offset SkipRequest       ;07+08
  688.               Dw    Offset LVDnRequest,Offset LVUpRequest       ;09+10
  689.               Dw    Offset RVDnRequest,Offset RVUpRequest       ;11+12
  690.               Dw    Offset LRVDRequest,Offset LRVURequest       ;13+14
  691. OrgIntOfs     Dw    0                            ;Original Int-Offset
  692. OrgIntSeg     Dw    0                            ;Original Int-Segment
  693. CDROMDrive    Dw    0                            ;First CD-ROM drive
  694.  
  695. ;====----  IOCTL Variables  ----==============================================
  696.  
  697. IOCTLBlock:                                      ;Standard IOCTL-block...
  698. IOCTLBlockLen Db    0                            ;Block length
  699. DevSubUnit    Db    0                            ;Device Sub Unit
  700. IOCTLCommand  Db    0                            ;Command code
  701. IOCTLStatus   Dw    0                            ;Device status
  702. IOCTLDummies1 Dd    0,0                          ;Never used
  703. IOCTLAddMode  Db    0                            ;0=HSG, 1=Red book
  704. CDStartPlay:                                     ;Start-sector for play
  705. IOCTLTransOfs Dw    0                            ; or transfer address
  706. IOCTLTransSeg Dw    0
  707. CDStopPlay:                                      ;Stop-sector for play
  708. IOCTLLen      Dw    0                            ; or IOCTL length
  709.               Dw    0
  710. IOCTLDummies2 Dd    0,0                          ;To fill up IOCTL-Block...
  711.  
  712. IOCTLBuffer   Db    MaxBlockLen Dup(0)           ;Buffer for CD-ROM requests
  713.  
  714. ;====----  CD Play variables  ----============================================
  715.  
  716. HSGIndex      Db    0,0,0,0                      ;Where PlayCD starts playing
  717. StartAddress  Db    0,0,0,0                      ;Used to simulate 'pause'
  718. MinIndex      Db    0,0,0,0                      ;First audio-sector
  719. MaxIndex      Db    0,0,0,0                      ;Last audio-sector
  720. MinTrack      Db    0                            ;First track number
  721. MaxTrack      Db    0                            ;Last track number
  722.  
  723. ;====----  DTCD kept resident up until here  ----=============================
  724.  
  725. EndOfTSR      Db    0
  726.  
  727. ;====----  Initialization  ----===============================================
  728.  
  729.      .8086                                       ;No 80286 detected yet...
  730.  
  731. Initialization:
  732.      Mov      Ah,9                               ;Display opening string
  733.      Mov      Dx,Offset WelcomeStr
  734.      Int      21h
  735. Detect80286:
  736.      Pushf                                       ;Standard check for 80286
  737.      Pushf
  738.      Pop      Ax
  739.      And      Ax,0FFFh
  740.      Push     Ax
  741.      Popf
  742.      Pushf
  743.      Pop      Ax
  744.      Popf
  745.      And      Ax,0F000h
  746.      Cmp      Ax,0F000h
  747.      Jz       ThisIsAnXT
  748. CheckInstalled:
  749.      Mov      Ah,4Fh                             ;Check if DTCD installed
  750.      Mov      Bx,'DT'
  751.      Mov      Cx,'CD'
  752.      Int      15h
  753.      Cmp      Ax,'Yo'                            ;Acknowledged ?
  754.      Jz       AlreadyInstalled                   ;Yes -> exit
  755.      Mov      Ax,1500h                           ;Check if CD-ROM installed
  756.      Sub      Bx,Bx
  757.      Int      2Fh
  758.      Or       Bx,Bx                              ;More than 0 CD-ROMs ?
  759.      Jz       NoCDROMInstalled                   ;No -> exit
  760.      Mov      [CDROMDrive],Cx                    ;Save first drive letter
  761.      Mov      Ax,1501h
  762.      Mov      Bx,Offset IOCTLBuffer
  763.      Int      2Fh                                ;Get drive info in buffer
  764.      Sub      Ch,Ch
  765.      Mov      Cl,[Bx]                            ;Get sub-unit in CL
  766.      Mov      [DevSubUnit],Cl                    ;Save sub-unit number
  767.      Add      [CDROMDrive],Cx                    ;Add subunit to drive letter
  768. DetectMSCDEX:
  769.      Mov      Ax,150Bh                           ;Check MSCDEX installed
  770.      Mov      Cx,[CDROMDrive]
  771.      Int      2Fh
  772.      Cmp      Bx,0ADADh                          ;Acknowledge ?
  773.      Jnz      NoMSCDEX                           ;No -> exit
  774. DetectMSCDEX21:
  775.      Mov      Ax,150Ch                           ;Check MSCDEX version
  776.      Int      2Fh
  777.      Cmp      Bx,020Ah                           ;Version 2.10
  778.      Jb       NotRightMSCDEX                     ;Before -> exit
  779. InstallTSR:
  780.      Mov      Ax,3515h                           ;Get interrupt vector
  781.      Int      21h
  782.      Mov      [OrgIntOfs],Bx                     ;Save interrupt vector
  783.      Mov      [OrgIntSeg],Es
  784.      Mov      Dx,Offset TSR                      ;Set interrupt vector to TSR
  785.      Mov      Ax,2515h
  786.      Int      21h
  787.      Mov      Ah,9                               ;Display end-string
  788.      Mov      Dx,Offset TSRInst
  789.      Int      21h
  790.      Mov      Dx,Offset EndOfTSR                 ;Keep TSR resident
  791.      Int      27h                                ;Terminate and Stay Resident
  792.  
  793. NoCDROMINstalled:
  794.      Mov      Dx,Offset NoCDROMStr               ;No CD ROM installed
  795.      Jmp      ErrorExit
  796. AlreadyInstalled:
  797.      Mov      Dx,Offset AlreadyInst              ;DTCD already loaded
  798.      Jmp      ErrorExit
  799. ThisIsAnXT:
  800.      Mov      Dx,Offset XTString                 ;No 80286 found
  801.      Jmp      ErrorExit
  802. NoMSCDEX:
  803.      Mov      Dx,Offset NoMSCDEXStr              ;No MSCDEX found
  804.      Jmp      ErrorExit
  805. NotRightMSCDEX:
  806.      Mov      Dx,Offset WrongMSCDEXSt            ;Not correct MSCDEX found
  807. ErrorExit:
  808.      Mov      Ah,9                               ;Display error string
  809.      Int      21h
  810.      Mov      Dx,Offset ExitString
  811.      Int      21h
  812.      Int      20h                                ;Exit
  813.  
  814. ;====----  String constants for initialization  ----==========================
  815.  
  816. WelcomeStr    Db    'DTown Audio-CD Player 1.01  (TSR Version).  Release: 25 January 1994.',13,10,13,10,'$'
  817. NoCDROMStr    Db    'No CD-ROM detected$'
  818. AlreadyInst   Db    'TSR already installed$'
  819. XTString      Db    'This program requires a 80286$'
  820. NoMSCDEXStr   Db    'MSCDEX not loaded$'
  821. WrongMSCDEXSt Db    'This program requires MSCDEX 2.1 or higher loaded$'
  822. ExitString    Db    '. DTCD halted...',13,10,'$'
  823. TSRInst       Db    'TSR successfully installed.  Read DTCD.DOC for keys...',13,10,'$'
  824. Code Ends
  825.      End Start
  826.